define(function(require) {

  var Backbone = require('backbone');
  var _ = require('underscore');
  var BaseView = require('../components/BaseView');
  var querystring = require('../libs/querystring');

  return BaseView.extend({
    type: 'PageView',
    //
    className: function() {
      return "PageView"
    },

    // ref: http://benmccormick.org/2015/01/05/marionette-view-life-cycles/
    // initialize is the suggested function for defining behavior on View setup.
    // It's a great place for setting up event listeners, and allows workings directly with the options passed to the View on creation.
    // 解析otions，此处options为页面的定义JSON
    constructor: function(options) {
      this.params = {}, // hold the parsed parameter from queryString
        // convert components option into Backbone Views
        this.components = _.chain(options.components || [])
        .map(function(each) {
          return this.createComponent(each);
        }.bind(this))
        .compact()
        .value();

      // call super
      BaseView.apply(this, arguments);
    },
    // Application可能直接加载页面，所以做个函数在这，维持和TarbarView等的一致性
    // 同时解析传递过来的参数供其他部分使用
    route: function(path, queryString) {
      if (queryString) {
        this.params = querystring.parse(queryString);
      }
      // also try to get path parameter, simple path parameter can be get here
      // can never override queryString parameter
      if (path && !_.has(this.params, 'path')) {
        this.params.path = path; // get path parameter
      }
      // 默认的隐藏tabbar的逻辑
      if (this.options.hideNav) {
        Backbone.$('nav.bar').hide();
      } else {
        Backbone.$('nav.bar').show();
      }
      // call post route callback
      this.postRoute();
    },
    // 路由完成之后执行的方法，在这里参数已经获取成功，可以在这里获取参数执行初始化填充动作
    postRoute: function() {},
    //
    onResume: function() {
      this.trigger("page:resume");
    },

    onPause: function() {
      this.trigger("page:pause");
    },

    remove: function() {
      // cleanup all components
      this.components && this.components.forEach(function(component) {
        component.remove();
      });
      // clean this params
      this.params = {};

      Backbone.View.prototype.remove.call(this);
    },

    render: function() {

      this.header && this.header.remove();
      this.$el.removeClass("page-with-header");
      // header
      if (this.options.header) {
        this.$el.addClass("page-with-header");
        this.header = this.getHeaderView(this.options.header);
        this.$el.append(this.header);
      }
      if(!this.options.hideNav){
        this.$el.addClass("page-with-tabbar");
      }
      // 在组件dom加入本页面dom之前调用,这时可以有一个机会修改component的属性
      this.onBeforeRender && this.onBeforeRender();

      if (this.options.template) {

        loader.getPageTemplate(this.options.template)
          .then(function(template) {
            var $template = $(template());

            // insert components into template
            _.chain(this.components)
              .filter(function(each) {
                return !!each.id;
              })
              .each(_.bind(function(each) { //FIXME if template is not a single node, there is a problem
                $template.find('component#' + each.id).replaceWith(each.render().el);
              }, this));

            this.$el.append($template);
            this.onRender && this.onRender();
            // dom填充完成之后触发一个事件，只在页面渲染的时候使用
            this.trigger("domReady");
          }.bind(this));

      } else {
        // components
        this.components.reduce(function($el, component) {
          var re = $el.append(component.render().el);
          component.onRender && component.onRender();
          return re;
        }, this.$el);
        this.onRender && this.onRender();
        // dom填充完成之后触发一个事件，只在页面渲染的时候使用
        this.trigger("domReady");
      }
      // bind to event handler
      this.setOptions(this.options);
      return this;
    },
    //通过递归遍历当前page下面所有的components,找到对应id的component
    findComponentInAll:function(components,componetid){
      var result;
      for(var i=0;i<components.length;i++){
        if(components[i].id==componetid){
          return components[i];
        }else if(components[i].components){
          result=this.findComponentInAll(components[i].components,componetid);
          if(result){
            break;
          }
        }
      }
      return result;
    },
  getHeaderView: function(header) {
      var header_el = $('<header class="bar bar-nav"></header>');

      function createNavItem(cfg) {
        var style ={"margin":"0 4px"};
        var icon = "";
        var imageClassName="";
        if(cfg.display=="imageUpload"){
           imageClassName="page-image-upload";
           style = {
             "background-image":"url("+cfg.icon+")"
           };
        }else{
           icon = cfg.icon;
        }
        if (cfg.type == "button" && cfg.text) {
          // 按钮风格，内有文字
          return $('<button class="btn">').text(cfg.text);
        } else if (cfg.type == "link" && !cfg.text) {
          // ios7链接风格，只有图标
          return $('<a></a>').addClass(icon).css(style).addClass(imageClassName);
        } else if (cfg.type == "link") {
          // ios7链接风格，有图标和文字
          var textStyle="";
        if(cfg.display=="imageUpload"){
            imageClassName = "page-image-text";
            style = {"background-image":"url("+cfg.icon+")"};
            textStyle="page-text";
          }
          var item = $('<button class="btn btn-link btn-nav">').css({margin:"0 4px", })
          if (cfg.icon) $('<span></span>').css(style).addClass(imageClassName).addClass(icon).appendTo(item);
          var iconLink =$('<span></span>').addClass(textStyle);
          iconLink.append(cfg.text)
          item.append(iconLink);
          return item;
        }
      }

      if (_.isArray(header.items)) {
        header.items.forEach(function(item, index) {
          var index_class = 'item-' + index;
          var item_el = createNavItem(item);
          item_el.addClass(index_class).addClass('pull-' + item.pull).appendTo(header_el);
          this.undelegate('click', '.' + index_class, this.onNavButtonClick.bind(null, item));
          this.delegate('click', '.' + index_class, this.onNavButtonClick.bind(null, item));
        }, this);
      }

      if (header.title) {
        var title = $('<h1 class="title"></h1>').text(header.title);
        header_el.append(title);
      }else{
        header_el.append('<h1 class="title"></h1>');
      }

      return header_el;
    },

    // 导航栏按钮事件响应
    onNavButtonClick: function(cfg) {
      if (cfg.href && cfg.href[0] == '#') {
        Backbone.history.navigate(cfg.href, {
          trigger: true
        });

      } else if (cfg.href) {
        window.location.href = cfg.href;
      } else if (cfg.event) {
        // 特别处理back事件，直接用浏览器的回退
        if (cfg.event == "back") {
          Backbone.history.history
           && Backbone.history.history.back();
         } else {
           Backbone.trigger(cfg.event, cfg);
         }
      }
    },

    createComponent: function(cfg) {

      var Component = window.library.getComponent(cfg.type);
      if (!Component) throw new Error('Component ' + cfg.type + ' Not Exists.');
      // *NOTE* component should not be rendered here, postpone to page render
      var component = new Component(cfg, this);
      component.el.setAttribute('data-type', cfg.type);
      component.setOptions(cfg); // TODO: should be removed ?

      return component;
    },

    addComponent: function(component) {
      if (component instanceof Backbone.View) {
        this.components.push(component);
        this.$el.append(component.el);
      } else {
        this.addComponent(this.createComponent(component));
      }
    },

    insertComponent: function(component, index) {
      if (component instanceof Backbone.View) {

        if (index < this.components.length) {
          // mark anchor component for insertAfter operation before splice
          var anchor_component = this.components[index];
          this.components.splice(index, 0, component);
          component.$el.insertBefore(anchor_component.el);
        } else {
          this.components.splice(index, 0, component);
          component.$el.appendTo(this.el);
        }

      } else {
        this.insertComponent(this.createComponent(component), index);
      }
    },

    removeComponent: function(index) {
      var component = this.components[index];
      this.components.splice(index, 1);
      component.remove();
    },

    findComponent: function(id) {
      var child = _.findWhere(this.components, {
        id: id
      });
      // TODO 这部分代码应该重构到containerView或者更上级中去，让所有容器具备此特性
      if (!child) console.warn('child not found: ' + id);
      return child;
    },
    // for a container, databind happened, pass it to the sub-components
    onDataBind: function(model) {
      if (this.components) {
        this.components.forEach(function(c){
          c.trigger("databind", model);
        });
      }
    },
    //在使用transition 动画的时候需要一个transitionEnd回调
    listenOneTransitionEnd: function(callback) {
      this.$el.bind("transitionend webkitTransitionEnd", function() {
        callback();
      });
    }
  });
});
